package com.facebook.react.modules.network;

import android.content.Context;

import com.facebook.react.modules.network.OkHttpClientProvider;
import com.facebook.react.modules.network.ReactCookieJarContainer;

import java.io.IOException;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Enumeration;
import java.util.concurrent.TimeUnit;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import okhttp3.OkHttpClient;


/**
 *
 * 支持https okHttp客户端
 *
 */
public class HttpsOkHttpClient {

    private static final String KEY_STORE_TYPE_P12 = "PKCS12";//证书类型
    private static final String KEY_STORE_PASSWORD = "646800";//证书密码（应该是客户端证书密码）

    /**
     * react native默认不支持https请求,这里提供支持https的OKHttpClient
     *
     * @return
     */
    public static OkHttpClient initCustomOkHttpClient(Context mContext) {
        OkHttpClient.Builder client = new OkHttpClient.Builder()
                .connectTimeout(0, TimeUnit.MILLISECONDS)
                .readTimeout(0, TimeUnit.MILLISECONDS)
                .writeTimeout(0, TimeUnit.MILLISECONDS)
                .cookieJar(new ReactCookieJarContainer());

        OkHttpClient.Builder builder = OkHttpClientProvider.enableTls12OnPreLollipop(client);

        builder.sslSocketFactory(getSSLSocketFactory(mContext))
                .hostnameVerifier(new HostnameVerifier() {
                    @Override
                    public boolean verify(String hostname, SSLSession session) {
                        return true; //忽略所有的认证，直接返回了true
                    }
                });
        return builder.build();
    }

    private static SSLSocketFactory getSSLSocketFactory(Context mContext) {
        SSLSocketFactory sslSocketFactory = null;
        try {
            TrustManager[] trustAllCerts = new TrustManager[]{
                new X509TrustManager() {
                    public void checkClientTrusted(X509Certificate[] chain, String authType) throws
                            CertificateException {
                    }
                    public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                    }
                    public X509Certificate[] getAcceptedIssuers() {
                        return new X509Certificate[0];
                    }
                }
            };
            KeyManager[] keyManagers = createKeyManagers(mContext);
            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(keyManagers, trustAllCerts, new SecureRandom());
            sslSocketFactory = sslContext.getSocketFactory();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return sslSocketFactory;
    }

    /**
     * 创建客户端Key
     * @param mContext
     * @return
     * @throws CertificateException
     * @throws IOException
     * @throws KeyStoreException
     * @throws NoSuchAlgorithmException
     * @throws UnrecoverableKeyException
     */
    private static KeyManager[] createKeyManagers(Context mContext) throws CertificateException,
            IOException, KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException {
        InputStream inputStream = mContext.getResources().getAssets().open("cert/ubmp_app_client.p12");
        KeyStore keyStore = KeyStore.getInstance(KEY_STORE_TYPE_P12);
        keyStore.load(inputStream, KEY_STORE_PASSWORD.toCharArray());
        printKeystoreInfo(keyStore);//for debug
        KeyManager[] managers;
        KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());//PKIX "X509")
        keyManagerFactory.init(keyStore, KEY_STORE_PASSWORD.toCharArray());
        managers = keyManagerFactory.getKeyManagers();
        return managers;
    }

    /**
     * 打印证书内容
     *
     * @param keystore
     * @throws KeyStoreException
     */
    private static void printKeystoreInfo(KeyStore keystore) throws KeyStoreException {
        Enumeration en = keystore.aliases();
        while (en.hasMoreElements()) {
            System.out.println("Alias: " + en.nextElement());
        }
    }

}
